import { deepMerge } from "@/utils"
import { loadToken } from "@/utils/cache"
import { message } from "ant-design-vue"
import { AxiosResponse } from "axios"
import { App, inject } from "vue"
import VueAxios from "./axios"
import { axiosTransform } from "./axiosTransform"
import { contentTypeEnum } from "./enum"
import { AxiosRequestOpts, RequestOptions, Result } from "./types"

/**
 * 传入axios拦截器方法，对axios请求进行拦截处理
 */

const transform: axiosTransform = {
  /**
   * @description: 请求拦截器处理
   */
  requestInterceptors: config => {
    // 请求之前处理config
    const token = loadToken()
    if (token) {
      // jwt token
      config.headers.Authorization = token
    }
    return config
  },
  /**
   *
   * @param res  AxiosResponse
   * @param options 对于返回数据配置
   */
  transformRequestData(res: AxiosResponse<Result>, options: RequestOptions) {
    console.log(options) // todos 后续增对与传入的参数动态返回自己所需要的的数据

    const { isTransformRequestResult } = options

    if (!isTransformRequestResult) {
      return res.data
    }
    const { status, msg, data } = res.data
    console.log(status, msg, data)
    if (status !== 1) {
      // 弹出异常信息
      message.error(msg, 1)
      return Promise.reject(false)
    }
    return data
  },
  requestInterceptorsCatch(err: any) {
    return Promise.reject(err)
  },
  responseInterceptors(response) {
    return response
  },
  responseInterceptorsCatch(err: any) {
    // 针对于特定异常数据处理。如 500 401 403
    message.error(err.message, 2)
    return Promise.reject(err)
  }
}

const defaultOpts = {
  timeout: 5 * 1000,
  headers: {
    "Content-type": contentTypeEnum.JSON,
    ignoreCancelToken: true
  },
  transform,
  requestOptions: {
    // 默认将prefix 添加到url
    joinPrefix: true,
    // 需要对返回数据进行处理
    isTransformRequestResult: true,
    // post请求的时候添加参数到url
    joinParamsToUrl: false,
    // 格式化提交参数时间
    formatDate: true,
    // 消息提示类型
    errorMessageMode: "none"
  }
}

/**
 * 创建VueAxios实例
 * @param opts 修改默认参数
 */

function createAxios(opts?: AxiosRequestOpts) {
  return new VueAxios(deepMerge(defaultOpts, opts || {}))
}

const symbolName = Symbol()

const install = (app: App, opts: AxiosRequestOpts) => {
  const vAxios: VueAxios = createAxios(opts)
  app.provide(symbolName, vAxios)
}

export const setupAxios = (app: App) => {
  app.use(install)
}

export function useVueAxios(): VueAxios {
  // eslint-disable-next-line
  return inject<VueAxios>(symbolName)!
}

const version = "1.0.0"

export { createAxios, version }

export const httpRequest = createAxios()

/**
 * 使用Vue插件形式install plugin，使用composition api 导入方法。
 */

// const service: AxiosInstance = Axios.create({
//   baseURL: process.env.VUE_APP_BASE_URL ? process.env.VUE_APP_BASE_URL : "",
//   timeout: 5000,

//   withCredentials: false
// })

// service.interceptors.request.use(config => {
//   return config
// })

// service.interceptors.response.use(
//   (response: AxiosResponse) => {
//     return response
//   },
//   //error处理
//   (error: AxiosError) => {
//     const { response } = error
//     console.log(response)
//     return Promise.reject(error)
//   }
// )

// /**
//  * 封装HttpRequest常用请求,composition-api方式
//  */
// interface IHttprequest {
//   http: <T, Res>(url: string, type: Method, data?: T) => Promise<AxiosResponse<Res>>
//   httpGet: <T, Res>(requestUrl: string, params?: T) => Promise<AxiosResponse<Res>>
//   HttpPost: <T, Res>(requestUrl: string, data: T) => Promise<AxiosResponse<Res>>
// }

// export function useHttpRequest(): IHttprequest {
//   const http = <T, Res>(url: string, type: Method, data?: T): Promise<AxiosResponse<Res>> => {
//     const axios = useAxios()
//     return axios({
//       url,
//       method: type,
//       data: data || {}
//     })
//   }

//   /**
//    * 封装GET请求
//    * @param requestUrl 请求api地址
//    * @param params get请求参数
//    */
//   const httpGet = <T, Res>(requestUrl: string, params?: T): Promise<AxiosResponse<Res>> => {
//     return Axios.get(requestUrl, { params })
//   }

//   /**
//    * 封装POST请求
//    * @param requestUrl post请求地址
//    * @param data 请求body
//    */

//   const HttpPost = <T, Res>(requestUrl: string, data: T): Promise<AxiosResponse<Res>> => {
//     return Axios.post(requestUrl, data)
//   }

//   return {
//     http,
//     httpGet,
//     HttpPost
//   }
// }
